package com.borya.service.mobile.impl;

import com.alibaba.fastjson.JSONObject;
import com.borya.constant.RedisConstant;
import com.borya.constant.SystemConstant;
import com.borya.dao.BlackIdCardDAO;
import com.borya.dao.RegistOrderInfoDAO;
import com.borya.dao.UserDAO;
import com.borya.dao.WebUserDAO;
import com.borya.framework.annotation.Autowired;
import com.borya.framework.annotation.Component;
import com.borya.framework.util.ObjectUtils;
import com.borya.model.db.*;
import com.borya.model.entity.FileInfo;
import com.borya.model.entity.SelfRegistering;
import com.borya.service.impl.BaseServiceImpl;
import com.borya.service.mobile.SdkService;
import com.borya.statuscode.StatusCode;
import com.borya.task.AutomaticAudittask;
import com.borya.task.model.RespInfo;
import com.borya.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.util.TextUtils;
import org.apache.log4j.Logger;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.Clock;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component("sdkServiceImpl")
public class SdkServiceImpl extends BaseServiceImpl implements SdkService {

    public Logger log = Logger.getLogger(getClass());
    @Autowired("userDAOImpl")
    private UserDAO userDAO;
    @Autowired("webUserDAOImpl")
    private WebUserDAO webUserDAO;
    @Autowired("blackIdCardDAO")
    private BlackIdCardDAO blackIdCardDAO;
    @Autowired("registOrderInfoDAO")
    private RegistOrderInfoDAO registOrderInfoDAO;

    @Override
    public String check(JSONObject json) {
        final String userId = json.getString("userId");
        final Integer detailType = json.getInteger(SystemConstant.Sdk.JsonKeys.JSON_KEY_DETAIL_TYPE);
        User user = userDAO.getSdkUser(userId, detailType);
        if (user == null) {
            log.warn(String.format("SDK源系统用户: %s 未注册签约", userId));
            return StatusCode.USER_NOT_FOUND.toJSON("您还未签约，请先完成签约");
        }
        Merchant merchant = userDAO.getMerchantStatus(user.getDealerId());
        if (ObjectUtils.isNull(merchant)) {
            log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 未查询到商户信息", userId, user.getUserId()));
            return StatusCode.USER_NOT_FOUND.toJSON("用户不存在");
        }
        int status = SystemConstant.Sdk.SignStatus.STATUS_UNDER_VIEW;
        String desc = "";
        switch (merchant.getStatus()) {
            case Merchant.STATUS_INACTIVATED:
            case Merchant.STATUS_HAS_DEVICE:
                RegistOrderInfo info = registOrderInfoDAO.getLastByUserId(user.getUserId());
                if (info.getOrderStatus() == 2) {
                    status = SystemConstant.Sdk.SignStatus.STATUS_REJECT;
                    desc = info.getRemarks();
                }
                break;
            case Merchant.STATUS_ACTIVED:
                final String tmsi = json.getString("tmsi");
                if (tmsi == null || tmsi.trim().length() == 0) {
                    log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 的tmsi为空，需要登录", userId, user.getUserId()));
                    return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
                }
                if (ObjectUtils.isEqual("0", tmsi)) {
                    log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 的tmsi为0，需要登录", userId, user.getUserId()));
                    return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
                }
                if (ObjectUtils.nonEqual(String.valueOf(user.getTmsi()), tmsi)) {
                    log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 传入Tmsi和DB中不一致; reqTmsi: %s, dbTmsi: %s", userId, user.getUserId(), tmsi, user.getTmsi()));
                    return StatusCode.TMSI_NO_MATCH.toJSON("您的帐号在其它终端上登录,请重新登录");
                }
                final long curTime = System.currentTimeMillis();
                if (user.getLastTime() < (curTime - Constant.TMSI_EXPIRED_HOUR * 60 * 60 * 1000)) {
                    log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s tmsi已过期; reqTmsi: %s, dbTmsi: %s", userId, user.getUserId(), tmsi, user.getTmsi()));
                    return StatusCode.TMSI_NO_MATCH.toJSON("用户信息过期,请重新登录");
                }
                status = SystemConstant.Sdk.SignStatus.STATUS_SIGNED;
                break;
        }
        StringBuilder builder = new StringBuilder(128);
        builder.append("{")
                .append("\"status\":\"").append(status).append("\"").append(",")
                .append("\"merchantType\":\"").append(merchant.getMerchantType()).append("\"").append(",")
                .append("\"desc\":\"").append(desc).append("\"")
                .append("}");
        return StatusCode.SUCCESS.toDiyJson(true, "data", builder.toString());
    }

    @Override
    public String register(JSONObject json) {
        final String userId = json.getString("userId");
        String phoneNumber = json.getString("phone");
        if (TextUtils.isBlank(phoneNumber)) {
            log.warn("参数 phone 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        final String phone = phoneNumber.replaceAll(" ", "");
        if (phone.length() != 11) {
            log.warn("参数 phone 长度错误");
            return StatusCode.PARAM_ERROR.toJSON("参数错误");
        }
        String type = json.getString("type");
        if (TextUtils.isBlank(type)) {
            log.warn("参数 type 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String idCardName = json.getString("idCardName");
        if (TextUtils.isBlank(idCardName)) {
            log.warn("参数 idCardName 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String idCardNumber = json.getString("idCardNumber");
        if (TextUtils.isBlank(idCardNumber)) {
            log.warn("参数 idCardNumber 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String idCardAddress = json.getString("idCardAddress");
        if (TextUtils.isBlank(idCardAddress)) {
            log.warn("参数 idCardAddress 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String idCardPeriod = json.getString("idCardPeriod");
        if (TextUtils.isBlank(idCardPeriod)) {
            log.warn("参数 idCardPeriod 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String cityCode = json.getString("cityCode");
        if (TextUtils.isBlank(cityCode)) {
            log.warn("参数 cityCode 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String cityName = json.getString("cityName");
        if (TextUtils.isBlank(cityName)) {
            log.warn("参数 cityName 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String frontPhoto = json.getString("frontPhoto");
        if (TextUtils.isBlank(frontPhoto)) {
            log.warn("参数 frontPhoto 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String backPhoto = json.getString("backPhoto");
        if (TextUtils.isBlank(backPhoto)) {
            log.warn("参数 backPhoto 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String handPhoto = json.getString("handPhoto");
        if (TextUtils.isBlank(handPhoto)) {
            log.warn("参数 handPhoto 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String imgSignature = json.getString("imgSignature");
        if (TextUtils.isBlank(imgSignature)) {
            log.warn("参数 imgSignature 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String imgAvatar = json.getString("imgAvatar");
        if (TextUtils.isBlank(imgAvatar)) {
            log.warn("参数 imgAvatar 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String storeAddress = json.getString("storeAddress");
        if (TextUtils.isBlank(storeAddress)) {
            log.warn("参数 storeAddress 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        String storeArea = json.getString("storeArea");
        if (TextUtils.isBlank(storeArea)) {
            log.warn("参数 storeArea 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        final Integer detailType = json.getInteger(SystemConstant.Sdk.JsonKeys.JSON_KEY_DETAIL_TYPE);
        final String dealerId = json.getString(SystemConstant.Sdk.JsonKeys.JSON_KEY_DEALER_ID);
        final String dealerName = json.getString(SystemConstant.Sdk.JsonKeys.JSON_KEY_DEALER_NAME);
        final String popChannel = json.getString(SystemConstant.Sdk.JsonKeys.JSON_KEY_POP_CHANNEL);
        final String popChannelName = json.getString(SystemConstant.Sdk.JsonKeys.JSON_KEY_POP_CHANNEL_NAME);
        final String lockKey = RedisConstant.LOCK_SDK_USER_REGISTER + userId;
        try {
            boolean lock = userDAO.redis_setNx(lockKey, "1", 30);
            if (!lock) {
                return StatusCode.PARAM_ERROR.json().msg("请求过快").toString();
            }
            final boolean res = blackIdCardDAO.idCardUsed(idCardNumber);
            if (!res) {
                log.error(String.format("商户被加入身份证名单tb_black_idcard, idCard= %s", idCardNumber));
                return StatusCode.SYSTEM_EXCEPTION.toJSON("身份证异常,请联系管理员");
            }
            User user = userDAO.getSdkUser(userId, detailType);
            boolean merchantExists = false;
            if (user != null) {
                Merchant merchant = userDAO.getMerchantStatus(user.getDealerId());
                if (merchant == null)
                    merchantExists = false;
                else {
                    if (merchant.getStatus() == Merchant.STATUS_ACTIVED) {
                        log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 已完成签约", userId, user.getUserId()));
                        return StatusCode.USERNAME_EXISTED.toJSON("你已完成签约，无需再签约。");
                    } else if (merchant.getStatus() == Merchant.STATUS_UNDER_REVIEW) {
                        log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 签约申请正在审核中", userId, user.getUserId()));
                        return StatusCode.USERNAME_EXISTED.toJSON("您的签约申请正在审核中");
                    }
                    merchantExists = true;
                }
            }
            final String realUserId = "SDK" + detailType + userId;
            Scope checkScope = webUserDAO.checkScope(1, storeArea);
            if (StringUtil.isNULL(checkScope)) {
                return StatusCode.PARAM_ERROR.toJSON("营运商和区域对应位置编号不存在");
            }
            ModelInfo modelInfo = userDAO.getDealerModel(dealerId);
            if (ObjectUtils.isNull(modelInfo)) {
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }
            SelfRegistering s;
            final long nowTime = Clock.systemDefaultZone().millis();
            final String date = DateUtils.format(nowTime, "yyMMddHHmmss");
            if (merchantExists) {
                s = userDAO.getVisitorInfo(user.getDealerId());
            } else {
                s = new SelfRegistering();
                s.setCreateTime(nowTime);
                s.setExtUserId(userId);
                s.setMerchantId("YT" + date + StringUtil.randomNumberString(6));
            }
            s.setSuper_dealer_id(dealerId);
            s.setSuper_dealer_name(dealerName);
            s.setPopchannel(popChannel);
            s.setPopchannel_name(popChannelName);
            String storeName = idCardName;
            if (StringUtils.equals("1", type)) {
                String licenseNumber = json.getString("licenseNumber");
                if (TextUtils.isBlank(licenseNumber)) {
                    log.warn("企业商户参数 licenseNumber 不能为空");
                    return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
                }
                storeName = json.getString("storeName");
                if (TextUtils.isBlank(storeName)) {
                    log.warn("企业商户参数 storeName 不能为空");
                    return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
                }
                final String licensePhoto = json.getString("licensePhoto");
                if (!checkImg(Constant.IMG_SAVE_PATH + licensePhoto))
                    return StatusCode.PARAM_ERROR.toJSON("不存在");
                s.setBusinessLicensePicture(licensePhoto);
                s.setIdCard(licenseNumber);
                s.setIdentityCardName(idCardName);
                s.setIdentityCard(idCardNumber);
                s.setIdentityCardAddress(idCardAddress);
            } else if (StringUtils.equals("2", type)) {
                s.setAddress(idCardAddress);
                s.setIdCard(idCardNumber);
            } else {
                log.warn(String.format("未知的签约类型 type: %s", type));
                return StatusCode.PARAM_ERROR.toJSON();
            }
            if (!checkImg(Constant.IMG_SAVE_PATH + frontPhoto)) {
                return StatusCode.PARAM_ERROR.toJSON("正面照不存在");
            }
            if (!checkImg(Constant.IMG_SAVE_PATH + backPhoto)) {
                return StatusCode.PARAM_ERROR.toJSON("背面照不存在");
            }
            if (!checkImg(Constant.IMG_SAVE_PATH + handPhoto)) {
                return StatusCode.PARAM_ERROR.toJSON("手持照片不存在");
            }
            if (StringUtils.isNotBlank(imgAvatar) && !checkImg(Constant.IMG_SAVE_PATH + imgAvatar)) {
                return StatusCode.PARAM_ERROR.toJSON("身份证头像不存在");
            }
            final String signMergePicture = imgSignature.substring(0, imgSignature.lastIndexOf(".")) + "_merge.png";
            if (!checkImg(Constant.IMG_SAVE_PATH + signMergePicture)) {
                return StatusCode.PARAM_ERROR.toJSON("签约照片不存在");
            }
            final String orderId = "SDKRE" + date + phone.substring(4);
            s.setScopeId(checkScope.getScopeId());
            s.setPhoneModel(modelInfo.getPhoneModel());
            s.setDiscountModel(modelInfo.getDiscountModel());
            s.setTransterModel(modelInfo.getIncomeTransterModel());
            s.setPackModel(modelInfo.getPackModel());
            s.setDwkModel(modelInfo.getDwkModel());
            s.setWhiteCardPay(modelInfo.getWhiteCardPay());
            s.setWhiteCardReturn(modelInfo.getWhiteCardReturn());
            s.setUser_name(idCardName);
            s.setPeriod(idCardPeriod);
            s.setOrderId(orderId);
            s.setModifyTime(nowTime);
            s.setMerchantType(Integer.valueOf(type));
            s.setCompany_name(storeName);
            s.setCityCode(cityCode);
            s.setCityName(cityName);
            s.setImgNo1(frontPhoto);
            s.setImgNo2(backPhoto);
            s.setImgNo3(handPhoto);
            s.setImgNo4(imgSignature);
            s.setUser_id(realUserId);
            s.setPhone(phone);
            s.setSignMergePicture(signMergePicture);
            s.setDealer_id(realUserId);
            s.setHeadPicture(imgAvatar);
            s.setStoreAddress(storeArea + storeAddress);
            s.setIsManage(0);
            s.setSourceType(3);
            s.setDetailType(detailType);
            s.setSuper_dealer_id(dealerId);
            s.setRegistType(2);
            s.setShopAddress(storeArea);
            s.setShopSpecificAddress(storeAddress);
            s.setOsversion(json.getString("osVersion"));
            s.setAppversion(json.getString("appVersion"));
            s.setOstype(json.getString("osType"));
            s.setPhonetype(json.getString("phoneType"));
            s.setNet(json.getString("net"));
            s.setApplicationID(json.getString("applicationID"));
            s.setHost_ip(json.getString("host_ip"));
            s.setLatitude(json.getString("latitude"));
            s.setLongitude(json.getString("longitude"));
            boolean r = userDAO.addSdkUser(user != null, merchantExists, s);
            if (!r) {
                log.warn("addSdkUser return " + r);
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }
            RespInfo respInfo = new RespInfo(orderId, "1", type,
                    "1", "1", s.getIdCard(), s.getUser_name(), s.getAddress(),
                    Constant.ums_url + s.getImgNo1(),
                    Constant.ums_url + s.getImgNo2(),
                    Constant.ums_url + s.getImgNo3());
            respInfo.setIdCardPeriod(idCardPeriod);
            if (StringUtils.isNotBlank(s.getHeadPicture())) {
                respInfo.setHeadImageLocation(Constant.ums_url + s.getHeadPicture());
            }
            AutomaticAudittask.getInstance().execute(JSONObject.toJSONString(respInfo));
            StringBuilder builder = new StringBuilder(126);
            builder.append("{")
                    .append("\"tmsi\":\"").append(s.getCreateTime()).append("\"")
                    .append("\"cityCode\":\"").append(s.getCityCode()).append("\"")
                    .append("\"cityName\":\"").append(s.getCityName()).append("\"")
                    .append("}");
            return StatusCode.SUCCESS.toDiyJson(true, "data", builder.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        } finally {
            userDAO.redis_del(lockKey);
        }
    }

    @Override
    public String uploadRegisterImg(JSONObject json) {
        try {
            String phoneNumber = json.getString("phone");
            if (TextUtils.isBlank(phoneNumber)) {
                log.warn("参数 phone 不能为空");
                return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
            }
            final String phone = phoneNumber.replaceAll(" ", "");
            if (phone.length() != 11) {
                log.warn("参数 phone 长度错误");
                return StatusCode.PARAM_ERROR.toJSON();
            }
            final int imgNo = json.getIntValue("imgNo");
            final String imgBase64 = json.getString("img");
            if (imgBase64 == null) {
                log.warn("参数 img 不能为空");
                return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
            }
            final String YYMMddHHmmssSSS = DateUtils.format("YYMMddHHmmssSSS");
            String imgName;
            String specialTag = "registing";
            final String subDir = 20 + YYMMddHHmmssSSS.substring(0, 6) + "/" + phone;
            switch (imgNo) {
                case SystemConstant.Sdk.ImageType.TYPE_ID_CARD_FRONT:// 正面
                    imgName = phone + "_front_" + YYMMddHHmmssSSS + ".png";
                    break;
                case SystemConstant.Sdk.ImageType.TYPE_ID_CARD_BACK:// 背面
                    imgName = phone + "_back_" + YYMMddHHmmssSSS + ".png";
                    break;
                case SystemConstant.Sdk.ImageType.TYPE_ID_CARD_HAND:// 手持
                    imgName = phone + "_hand_" + YYMMddHHmmssSSS + ".png";
                    break;
                case SystemConstant.Sdk.ImageType.TYPE_SIGNATURE:// 签名
                    specialTag = "sign";
                    imgName = phone + "_sign_" + YYMMddHHmmssSSS + ".png";
                    break;
                case SystemConstant.Sdk.ImageType.TYPE_BUSINESS_LICENSE://营业执照
                    imgName = phone + "_license_" + YYMMddHHmmssSSS + ".png";
                    break;
                case SystemConstant.Sdk.ImageType.TYPE_AVATAR:// 识别的小头像
                    imgName = phone + "_avatar_" + YYMMddHHmmssSSS + ".png";
                    break;
                default:
                    return StatusCode.PARAM_ERROR.toJSON("参数照片编号错误");
            }
            FileInfo fileInfo = FileInfo.newInstance(specialTag, subDir, imgName);
            final String parentPath = fileInfo.getParentPath();
            boolean ok = ImageUtils.writeImg(parentPath, imgName, imgBase64);
            if (!ok) {
                return StatusCode.SYSTEM_EXCEPTION.toJSON("上传图片失败，请稍后重试");
            }
            final String imgNewName = imgName.substring(0, imgName.length() - 4) + "_narrow.png";
            final String newRelatePath = fileInfo.getRelateDir() + imgNewName;
            String waterText = "办理时间" + DateUtils.format("yyyy-MM-dd HH:mm:ss") + "仅用于远特通信业务办理";
            ImageUtils.waterWordsAuto(waterText, fileInfo.getParentPath() + "/" + imgName, fileInfo.getParentPath() + "/" + imgNewName, Color.white);
            AliOSSUtil.UploadResult upload = AliOSSUtil.upload(fileInfo.getParentPath() + imgNewName, newRelatePath);
            if (!upload.isFlag()) {
                log.info("图片上传oss失败，图片路径：" + fileInfo.getParentPath() + imgNewName);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("图片上传oss失败，请稍后重试");
            }
            if (imgNo == SystemConstant.Sdk.ImageType.TYPE_SIGNATURE) {
                final String filePathName = fileInfo.getFilePath();
                final String signMergePicture = phone + "_sign_" + YYMMddHHmmssSSS + "_merge.png";
                saveImgNarrow(filePathName, fileInfo.getParentPath(), phone, signMergePicture);
                String signMergeRelate = fileInfo.getRelateDir() + signMergePicture;
                AliOSSUtil.UploadResult upload1 = AliOSSUtil.upload(fileInfo.getParentPath() + signMergePicture,
                        signMergeRelate.substring(1));
                if (!upload1.isFlag()) {
                    log.info("图片上传oss失败，图片路径：" + fileInfo.getParentPath() + signMergePicture);
                    return StatusCode.SYSTEM_EXCEPTION.toJSON("图片上传oss失败，请稍后重试");
                }
            }
            return StatusCode.SUCCESS.toDiyJson(true, "data", "{\"imgName\":\"" + newRelatePath + "\"}");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
    }

    @Override
    public String getLoginCode(JSONObject json) {
        String phoneNumber = json.getString("phone");
        if (TextUtils.isBlank(phoneNumber)) {
            log.warn("参数 phone 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        final String phone = phoneNumber.replaceAll(" ", "");
        if (phone.length() != 11) {
            log.warn("参数 phone 长度错误");
            return StatusCode.PARAM_ERROR.toJSON();
        }
        final String userId = json.getString("userId");
        final Integer detailType = json.getInteger(SystemConstant.Sdk.JsonKeys.JSON_KEY_DETAIL_TYPE);
        User user = userDAO.getSdkUser(userId, detailType);
        if (user == null) {
            log.warn(String.format("SDK源系统用户: %s 未注册签约", userId));
            return StatusCode.USER_NOT_FOUND.toJSON("您还未签约，请先完成签约");
        }
        Merchant merchant = userDAO.getMerchantStatus(user.getDealerId());
        if (ObjectUtils.isNull(merchant)) {
            log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 未查询到商户信息", userId, user.getUserId()));
            return StatusCode.USER_NOT_FOUND.toJSON("您还未签约，请先完成签约");
        } else if (merchant.getStatus() == Merchant.STATUS_UNDER_REVIEW) {
            log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 签约申请正在审核中", userId, user.getUserId()));
            return StatusCode.CONDITION_DEL_ING.toJSON("您的签约申请正在审核中");
        } else if (merchant.getStatus() == Merchant.STATUS_INACTIVATED
                || merchant.getStatus() == Merchant.STATUS_HAS_DEVICE) {
            RegistOrderInfo info = registOrderInfoDAO.getLastByUserId(user.getUserId());
            if (info.getOrderStatus() == 2) {
                log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 签约申请已被拒绝", userId, user.getUserId()));
            } else {
                log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 签约未完成", userId, user.getUserId()));
            }
            return StatusCode.USER_NOT_FOUND.toJSON("您还未签约，请先完成签约");
        } else if (merchant.getFlag() == Merchant.Flag.WRITE_OFF) {
            log.warn(String.format("SDK源系统用户: %s 卡盟系统用户: %s 商户已被注销", userId, user.getUserId()));
            return StatusCode.NO_AUTHORITY.toJSON("您所在商户已被注销,具体请联系管理员");
        }
        try {
            String key = RedisConstant.SDK_LOGIN_CODE + userId;
            Long t = userDAO.redis_ttl(key);
            if (t == null) {
                String code = StringUtil.randomNumberString(6);
                String content = "尊敬的用户,您的登录验证码为：" + code + "。";
                boolean s = SmsUtils.sendMsg(phone, content);
                if (!s) {
                    log.warn("短信发送失败");
                    return StatusCode.SYSTEM_EXCEPTION.toJSON("验证码发送失败，请稍候再试");
                }
                userDAO.redis_setNx(key, code, 120);
            }
            return StatusCode.SUCCESS.toJSON();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
    }

    @Override
    public String login(JSONObject json) {
        String authCode = json.getString("authCode");
        if (TextUtils.isBlank(authCode)) {
            log.warn("参数 authCode 不能为空");
            return StatusCode.PARAM_ERROR.toJSON("参数不能为空");
        }
        final String userId = json.getString("userId");
        final Integer detailType = json.getInteger(SystemConstant.Sdk.JsonKeys.JSON_KEY_DETAIL_TYPE);
        User user = userDAO.getSdkUser(userId, detailType);
        if (user == null) {
            log.warn(String.format("SDK源系统用户: %s 未注册签约", userId));
            return StatusCode.USER_NOT_FOUND.toJSON("您还未签约，请先完成签约");
        }
        try {
            String key = RedisConstant.SDK_LOGIN_CODE + userId;
            String code = userDAO.redis_get(key);
            if (code != null) {
                if (StringUtils.equals(authCode, code)) {
                    final String osVersion = json.getString("osVersion");
                    final String appVersion = json.getString("appVersion");
                    final String osType = json.getString("osType");
                    final String phoneType = json.getString("phoneType");
                    final String net = json.getString("net");
                    final String applicationID = json.getString("applicationID"); // 应用ID
                    final String packageName = json.getString("packageName");
                    final String hostIp = json.getString("host_ip");
                    final String latitude = json.getString("latitude");
                    final String longitude = json.getString("longitude");
                    final long curTime = System.currentTimeMillis();
                    user.setApplicationID(applicationID);
                    user.setAppVersion(appVersion);
                    user.setNet(net);
                    user.setOsType(osType);
                    user.setOsVersion(osVersion);
                    user.setPhoneType(phoneType);
                    user.setPackageName(packageName);
                    user.setTmsi(curTime);
                    user.setLastTime(curTime);
                    user.setHostIp(hostIp);
                    user.setLatitude(latitude);
                    user.setLongitude(longitude);
                    boolean update = userDAO.updateUser(user);
                    if (!update) {
                        log.warn("更新客户端用户的信息失败");
                        return StatusCode.SYSTEM_EXCEPTION.toJSON();
                    }
                    JSONObject dtJson = new JSONObject();
                    dtJson.put("tmsi", String.valueOf(curTime));
                    dtJson.put("cityCode", user.getCityCode());
                    dtJson.put("cityName", user.getCityName());
                    dtJson.put("userName", user.getUserName());
                    return StatusCode.SUCCESS.toDiyJson(true, "data", dtJson.toJSONString());
                } else {
                    return StatusCode.IDENTIFY_CODE_ERROR.toJSON("验证码错误，请重新输入");
                }
            } else {
                return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码已过期，请重新获取");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
    }

    private void saveImgNarrow(final String signImgPath, final String destDir, String phone, String fileNameMerge) throws Exception {
        String narrowPath = "/agent_merchant_agreement1.png";
        log.info(String.format("文件相对位置: %s，当前类：%s", narrowPath, getClass().getSimpleName()));
        InputStream in = getClass().getResourceAsStream(narrowPath);
        final String signImgCopyPath = destDir + fileNameMerge + "_copy.png";
        File signImgCopyFile = new File(signImgCopyPath);
        FileUtils.copyFile(new File(signImgPath), signImgCopyFile);
        if (Objects.isNull(in)) {
            log.error(String.format("输入流不能为空，文件相对位置: %s", narrowPath));
            throw new RuntimeException("输入流不能为空");
        }
        Image src1 = javax.imageio.ImageIO.read(in);
        final int width1 = src1.getWidth(null);

        Image src3 = javax.imageio.ImageIO.read(signImgCopyFile);
        final int width2 = src3.getWidth(null);
        final int height2 = src3.getHeight(null);
        if (width1 != width2) {
            ImageUtils.narrowImage(signImgCopyPath, width1, (int) ((double) width1 / width2 * height2));
        }
        final String date = DateUtils.format("yyyy-MM-dd HH:mm:ss");
        List<String> list = new ArrayList<>();
        list.add("签约时间:" + date);
        list.add("签约人:" + phone);
        ImageUtils.createImg(destDir, fileNameMerge + "_water.png", list, width1);
        File file2 = new File(destDir + fileNameMerge + "_water.png");
        ImageUtils.mergeImageVertically(src1, file2, destDir + "/" + fileNameMerge + "_2.png");
        File fileTmpe2 = new File(destDir + "/" + fileNameMerge + "_2.png");
        Image src2_ = javax.imageio.ImageIO.read(fileTmpe2);
        Image src3_ = javax.imageio.ImageIO.read(signImgCopyFile);
        ImageUtils.mergeImageVertically(src2_, src3_, destDir + "/" + fileNameMerge);
        clearAndDeleteFile(signImgCopyFile);
        clearAndDeleteFile(fileTmpe2);
        clearAndDeleteFile(file2);
    }

    private void clearAndDeleteFile(File file) {
        if (file == null) {
            return;
        }
        if (file.exists()) {
            try (FileOutputStream out = new FileOutputStream(file);) {
                out.write(new byte[1]);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
            file.delete();
        }
    }

    private boolean checkImg(String dir) {
        File f = new File(dir);
        return f.exists();
    }
}